import 'package:flutter/material.dart';

class ColorPainter extends CustomPainter{

  final ColorNotifier colorNotifier;
  final int width;
  final int height;
  final int fontSize;
  ColorPainter({
    required this.colorNotifier,
    required this.width,
    required this.height,
    required this.fontSize,
  }):super(repaint: colorNotifier){
    painter = Paint();
  }

  final colors = [
    Colors.green,
    Colors.blue,
    Colors.orange,
    Colors.purple,
    Colors.grey,
    Colors.cyan,
    Colors.yellow,
    Colors.pink
  ];

  late Paint painter;
  @override
  void paint(Canvas canvas, Size size) {
    double sizeWidth = size.width.floorToDouble();
    double sizeHeight = size.height.floorToDouble();

    double widthPer = sizeWidth / width;
    double heightPer = sizeHeight / height;

    double endWidth = widthPer > heightPer ? heightPer * width : sizeWidth;
    widthPer = widthPer > heightPer ? heightPer : widthPer;
    double endHeight = widthPer * height;

    double offsetX = (size.width - endWidth) / 2;
    painter.color = Colors.black;
    canvas.drawRect(Rect.fromLTWH(offsetX, 0, endWidth, endHeight), painter);

    double circleWidth = widthPer * 0.8;
    double radius = circleWidth / 2;

    int len = colorNotifier.colors.length;
    if(len == 0){
      return;
    }
    int maxLines = colorNotifier.maxLines;
    int index = 0;
    for(double i = 0; i < endHeight; i += widthPer){
      for(double j = offsetX; j < endWidth; j += widthPer){
        if(index >= len) return;
        double startX = j + ((widthPer - circleWidth) / 2) + radius;
        double startY = i + ((widthPer - circleWidth) / 2) + radius;
        final dy = (index ~/ width);
        final start = ((height - (fontSize * maxLines)) / 2);
        final end = start + (fontSize * maxLines);
        Color color = dy >= start && dy < end && colorNotifier.colors[index].value == 0 ? colors[(dy - start) ~/ fontSize] : colorNotifier.colors[index];
        painter.color = color;
        canvas.drawCircle(Offset(startX, startY), radius, painter);
        index++;
      }
    }

  }

  @override
  bool shouldRepaint(ColorPainter oldDelegate) {
    return oldDelegate.colorNotifier.colors != colorNotifier.colors
    || oldDelegate.width != width || oldDelegate.height != height
    || oldDelegate.fontSize != fontSize
    ;
  }

}

class ColorNotifier extends ChangeNotifier{

  List<Color> _colors = [];

  List<Color> get colors => _colors;

  set colors(List<Color> value) {
    _colors = value;
    notifyListeners();
  }

  int _maxLines = 0;

  int get maxLines => _maxLines;

  set maxLines(int value) {
    _maxLines = value;
  }
}